package org.budo.dubbo.protocol.http.authentication;

import java.io.Serializable;
import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.budo.dubbo.protocol.http.authentication.AuthenticationCheckService.Fail;
import org.budo.dubbo.protocol.http.exception.remoting.AuthenticationCheckException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;

/**
 * Interceptor for 用户身份认证，Aop过滤器
 * 
 * @author lmw
 * @see org.budo.dubbo.protocol.http.authentication.AuthenticationCheck
 */
@Order(1000)
public class AuthenticationCheckMethodInterceptor extends AbstractAuthenticationCheckInterceptor implements MethodInterceptor {
    private static final Logger log = LoggerFactory.getLogger(AuthenticationCheckMethodInterceptor.class);

    public Object invoke(MethodInvocation invocation) throws Throwable {
        Method method = invocation.getMethod();

        if (!AuthenticationCheckUtil.requireAuthenticationCheck_aop(invocation.getMethod().getDeclaringClass(), method)) {
            return invocation.proceed();
        }

        AuthenticationCheckService checkService = this.getAuthenticationCheckService();
        Serializable userPrincipal = checkService.getAuthenticationPrincipal();

        if ((null == userPrincipal || userPrincipal instanceof Fail)) {
            log.error("#35 userPrincipal=" + userPrincipal + ", checkService=" + checkService + ", invocation=" + invocation);
            throw new AuthenticationCheckException(method, (Fail) userPrincipal); // 异常跳出流程
        }

        return invocation.proceed();
    }
}
